package com.ia.aistream.manager.operating.util.visio;

import com.ia.aistream.common.utils.spring.SpringUtils;
import com.ia.aistream.manager.dxfcomponent.conf.DrawConf;
import com.ia.aistream.model.operating.dto.visio.ResultVisioDto;
import com.ia.aistream.model.operating.dto.visio.VisioDto;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Ymj
 */
public class PdfToPngUtil {

    /**
     * dpi越大转换后越清晰，相对转换速度越慢
     */
    private static final Integer DPI = 200;

    /**
     * 转换后的图片类型
     */
    private static final String IMG_TYPE = "png";

    /****
     * 远程调用服务实现Visio转png文件
     * @param visioPath
     * @return
     */
    public static String visioToPng(String visioPath) throws Exception{
        // 远程访问参数
        VisioDto visioDto = new VisioDto();
        visioDto.setFilePath(visioPath);
        visioDto.setFileName("ddd");
        // 发送请求
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity request = new HttpEntity<>(visioDto, headers);
        RestTemplate restTemplate = SpringUtils.getBean("restTemplate");

        DrawConf drawConf = SpringUtils.getBean("drawConf");
        ResponseEntity<ResultVisioDto> responseEntity = restTemplate.postForEntity(drawConf.getVisioTool(), request, ResultVisioDto.class);
        ResultVisioDto body = responseEntity.getBody();
        String pdfFile = (String) body.getData().get("pdfFile");

        // 实现PDF转图片
        return PdfToPngUtil.convertImg(pdfFile);
    }

    /***
     * 实现PDF转化为图片
     * @param filePath
     * @return
     * @throws Exception
     */
    public static String convertImg(String filePath) throws Exception{
        byte[] bytesByFile = getBytesByFile(filePath);
        List<byte[]> bytes = pdfToImage(bytesByFile);
        String imgPath = filePath.replace(".pdf", ".png");
        FileOutputStream fos = new FileOutputStream(imgPath);
        for (byte[] b:bytes){
            fos.write(b);
        }
        fos.flush();
        fos.close();

        return imgPath;
    }
    /**
     * PDF转图片
     * @param fileContent PDF文件的二进制流
     * @return 图片文件的二进制流
     */
    private static List<byte[]> pdfToImage(byte[] fileContent) throws IOException {
        List<byte[]> result = new ArrayList<>();
        try (PDDocument document = PDDocument.load(fileContent)) {
            PDFRenderer renderer = new PDFRenderer(document);
            for (int i = 0; i < document.getNumberOfPages(); ++i) {
                BufferedImage bufferedImage = renderer.renderImageWithDPI(i, DPI);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, IMG_TYPE, out);
                result.add(out.toByteArray());
            }
        }
        return result;
    }

    private static byte[] getBytesByFile(String pathStr) {
        File file = new File(pathStr);
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            byte[] data = bos.toByteArray();
            bos.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
